import { InjectionKey, inject, provide } from "vue"

const API_BASE_URL = import.meta.env.VITE_API_BASE_URL;

export const InjectKey_ApiBaseUrl: InjectionKey<string> = Symbol("inject_base_url");
export const InjectKey_HttpClient: InjectionKey<FetchClient> = Symbol("inject_http_client");

export interface FetchClient { fetch(url: RequestInfo, init?: RequestInit): Promise<Response> }

const fetchClient: FetchClient = {
    fetch(url, init) {
        return window.fetch(url, init)
    },
}

export const useHttp = () => {
    return inject(InjectKey_HttpClient);
}

export const provideHttp = () => {
    provide(InjectKey_HttpClient, fetchClient);
}

export const useBaseUrl = () => {
    return inject(InjectKey_ApiBaseUrl);
}

export const provideBaseUrl = () => {
    return provide(InjectKey_ApiBaseUrl, API_BASE_URL);
}

export const useApiConfig = () => {
    return {
        baseUrl: useBaseUrl(),
        http: useHttp()
    }
}

/**
 * 根据client类型创建实例
 * @param clientType client类型
 * @returns 
 */
export function useClient<TClient>(clientType: (new (baseUrl?: string, http?: FetchClient) => TClient)): TClient {
    const { baseUrl, http } = useApiConfig()

    return new clientType(baseUrl, http)
}